#include "my_u8g2.h"
#include "u8g2_graph.h"
#include "Arduino.h"
#include "config.h"
#include "plog.h"

U8G2_SSD1306_128X64_NONAME_F_HW_I2C *u8g2_displayer = nullptr;

uint32_t last_active_time = 0; // 最后活动时间戳
bool display_on = true;        // 显示状态

void U8G2_init(void)
{
  // u8g2_displayer = new U8G2_SSD1306_128X64_NONAME_F_HW_I2C(U8G2_R0, /* reset=*/ U8X8_PIN_NONE, /* clock=*/ I2C_SCL_PIN, /* data=*/ I2C_SDA_PIN);
  u8g2_displayer = new U8G2_SSD1306_128X64_NONAME_F_HW_I2C(U8G2_R0, /* reset=*/U8X8_PIN_NONE);
  u8g2_displayer->begin();
}

void U8G2_sleep(void)
{
  u8g2_displayer->setPowerSave(1);
  display_on = false;
  LOG_INFO("U8G2 go to sleep...");
}

void U8G2_wakeup(void)
{
  if (!display_on)
  {
    u8g2_displayer->setPowerSave(0);
    display_on = true;
    u8g2_displayer->sendBuffer();
    delay(500);
    LOG_INFO("U8G2 wake up!");
  }
}

void U8G2_sleep_check(void)
{
  if (display_on && (millis() - last_active_time >= U8G2_SLEEP_TIME))
  {
    U8G2_sleep();
  }
}

void U8G2_refresh_active_time(void)
{
  last_active_time = millis();
}

void drawLogo(U8G2 *u8g2)
{
  // if (!display_on)
  //   return;

  u8g2->setFontMode(1); // Transparent
  u8g2->setFontDirection(0);
  u8g2->setFont(u8g2_font_inb24_mf);
  u8g2->drawStr(0, 30, "U");

  u8g2->setFontDirection(1);
  u8g2->setFont(u8g2_font_inb30_mn);
  u8g2->drawStr(21, 8, "8");

  u8g2->setFontDirection(0);
  u8g2->setFont(u8g2_font_inb24_mf);
  u8g2->drawStr(51, 30, "g");
  u8g2->drawStr(67, 30, "\xb2");

  u8g2->drawHLine(2, 35, 47);
  u8g2->drawHLine(3, 36, 47);
  u8g2->drawVLine(45, 32, 12);
  u8g2->drawVLine(46, 33, 12);
}

void drawURL(U8G2 *u8g2)
{
  // if (!display_on)
  //   return;

  u8g2->setFont(u8g2_font_4x6_tr);
  if (u8g2->getDisplayHeight() < 59)
  {
    u8g2->drawStr(89, 20, "github.com");
    u8g2->drawStr(73, 29, "/olikraus/u8g2");
  }
  else
  {
    u8g2->drawStr(1, 54, "github.com/olikraus/u8g2");
  }
}

void U8G2_example_logo(void)
{
  // if (!display_on)
  //   return;

  u8g2_displayer->clearBuffer();
  drawLogo(u8g2_displayer);
  drawURL(u8g2_displayer);
  u8g2_displayer->sendBuffer();
}

void U8G2_welcome(void)
{
  // if (!display_on)
  //   return;
  u8g2_displayer->clearBuffer();
  u8g2_displayer->setFont(u8g2_font_lubBI24_tf);
  u8g2_displayer->drawStr(12, 32, "PAqm");
  u8g2_displayer->drawStr(14, 64, "Start!");
  u8g2_displayer->sendBuffer();
}

void U8G2_message(char *msg)
{
  // if (!display_on)
  //   return;
  u8g2_displayer->clearBuffer();
  u8g2_displayer->setFont(u8g2_font_8x13_tr);
  u8g2_displayer->drawStr(0, 32, msg);
  u8g2_displayer->sendBuffer();
}

void U8G2_wifi_wifimanager_waiting(const char *ssid, const char *ip)
{
  if (!display_on)
    return;

  u8g2_displayer->clearBuffer();
  // u8g2_font_ncenB10_tf
  u8g2_displayer->setFont(u8g2_font_6x10_tr);

  u8g2_displayer->drawStr(0, 16, (String("1.connect ") + String(ssid)).c_str());
  u8g2_displayer->drawStr(0, 32, (String("2.visit ") + String(ip)).c_str());
  u8g2_displayer->drawStr(0, 48, "3.config your WiFi~");
  u8g2_displayer->sendBuffer();
}

void U8G2_wifi_wifimanager_finished(const char *ssid, const char *ip)
{
  // if (!display_on)
  //   return;

  u8g2_displayer->clearBuffer();
  u8g2_displayer->setFont(u8g2_font_6x10_tr);

  u8g2_displayer->drawStr(0, 16, (String("linked ") + String(ssid)).c_str());
  u8g2_displayer->drawStr(0, 32, (String("got IP ") + String(ip)).c_str());
  u8g2_displayer->sendBuffer();
}

void U8G2_web_server_started(const char *ssid, const char *pwd, const char *ip)
{
  // if (!display_on)
  //   return;

  u8g2_displayer->clearBuffer();
  u8g2_displayer->setFont(u8g2_font_8x13_tr);
  u8g2_displayer->drawStr(6, 16, "web server run!");
  u8g2_displayer->drawStr(0, 32, (String("ssid: ") + String(ssid)).c_str());
  u8g2_displayer->drawStr(0, 48, (String("pwd: ") + String(pwd)).c_str());
  u8g2_displayer->drawStr(0, 63, "ip:192.168.4.1");
  u8g2_displayer->sendBuffer();
}

void U8G2_sensor_raw_data(Sensor_result_t *res)
{
  // if (!display_on)
  //   return;

  u8g2_displayer->clearBuffer();

  u8g2_displayer->setFont(u8g2_font_8x13_tr);
  u8g2_displayer->drawStr(0, 13, "eCO2:       ppm");
  u8g2_displayer->drawStr(50, 13, String(res->gs.eco2).c_str());

  u8g2_displayer->drawStr(0, 26, "TVOC:       ppb");
  u8g2_displayer->drawStr(50, 26, String(res->gs.tvoc).c_str());

  u8g2_displayer->drawStr(0, 39, "Temp:       C");
  u8g2_displayer->drawStr(50, 39, String(res->es.temperature).c_str());

  u8g2_displayer->drawStr(0, 52, "Humd:       %");
  u8g2_displayer->drawStr(50, 52, String(res->es.humidity).c_str());

  u8g2_displayer->drawStr(0, 64, "Pres:        kPa");
  u8g2_displayer->drawStr(50, 64, String(res->es.pressure / float(1000)).c_str());

  u8g2_displayer->sendBuffer();
}

void U8G2_gas_sensor_raw_data(GS_result_t *res)
{
  // if (!display_on)
  //   return;

  u8g2_displayer->clearBuffer();

  u8g2_displayer->setFont(u8g2_font_fur11_tf);
  u8g2_displayer->drawStr(0, 24, " eCO2:          ppm");
  u8g2_displayer->setFont(u8g2_font_fur14_tn);
  u8g2_displayer->drawStr(48, 24, String(res->eco2).c_str());

  u8g2_displayer->setFont(u8g2_font_fur11_tf);
  u8g2_displayer->drawStr(0, 50, "TVOC:          ppb");
  u8g2_displayer->setFont(u8g2_font_fur14_tn);
  u8g2_displayer->drawStr(48, 50, String(res->tvoc).c_str());

  u8g2_displayer->sendBuffer();
}

U8G2_Graph gas_eco2_graph_bar(U8G2_Graph::BAR,
                              0, U8G2_HEIGHT - U8G2_CHART_HEIGHT_DEFAULT,
                              U8G2_WIDTH, U8G2_CHART_HEIGHT_DEFAULT,
                              EC02_MIN_VAL, EC02_MAX_VAL);
// note：字符原点是左下角，图像原点是左上角
void U8G2_gas_sensor_eco2_graph(uint16_t eco2, bool reset)
{
  // if (!display_on)
  //   return;

  u8g2_displayer->clearBuffer();

  u8g2_displayer->setFont(u8g2_font_fur11_tf);
  u8g2_displayer->drawStr(0, 16, "eCO2:           ppm");
  u8g2_displayer->setFont(u8g2_font_fur14_tn);
  u8g2_displayer->drawStr(48, 16, String(eco2).c_str());

  if (reset)
    gas_eco2_graph_bar.Reset();

  gas_eco2_graph_bar.AddDataPoint(eco2);
  gas_eco2_graph_bar.Show();

  u8g2_displayer->sendBuffer();
}

U8G2_Graph gas_tvoc_graph_bar(U8G2_Graph::LINE,
                              0, U8G2_HEIGHT - U8G2_CHART_HEIGHT_DEFAULT,
                              U8G2_WIDTH, U8G2_CHART_HEIGHT_DEFAULT,
                              TVOC_MIN_VAL, TVOC_MAX_VAL);
void U8G2_gas_sensor_tvoc_graph(uint16_t tvoc, bool reset)
{
  // if (!display_on)
  //   return;

  u8g2_displayer->clearBuffer();

  u8g2_displayer->setFont(u8g2_font_fur11_tf);
  u8g2_displayer->drawStr(0, 16, "TVOC:           ppb");
  u8g2_displayer->setFont(u8g2_font_fur14_tn);
  u8g2_displayer->drawStr(50, 16, String(tvoc).c_str());

  if (reset)
    gas_tvoc_graph_bar.Reset();

  gas_tvoc_graph_bar.AddDataPoint(tvoc);
  gas_tvoc_graph_bar.Show();

  u8g2_displayer->sendBuffer();
}

U8G2_Graph env_temp_graph_bar(U8G2_Graph::LINE,
                              0, U8G2_HEIGHT - U8G2_CHART_HEIGHT_DEFAULT,
                              U8G2_WIDTH, U8G2_CHART_HEIGHT_DEFAULT,
                              TEMP_MIN_VAL, TEMP_MAX_VAL);
void U8G2_env_sensor_temp_graph(float temp, bool reset)
{
  // if (!display_on)
  //   return;

  u8g2_displayer->clearBuffer();

  u8g2_displayer->setFont(u8g2_font_fur11_tf);
  u8g2_displayer->drawStr(0, 16, "Temp:            C");
  u8g2_displayer->setFont(u8g2_font_fur14_tn);
  u8g2_displayer->drawStr(50, 16, String(temp).c_str());

  if (reset)
    env_temp_graph_bar.Reset();

  env_temp_graph_bar.AddDataPoint(temp);
  env_temp_graph_bar.Show();

  u8g2_displayer->sendBuffer();
}
